package com.example.student_system.service.impl;

import com.example.student_system.entity.Student;
import com.example.student_system.exception.StudentException;
import com.example.student_system.repository.StudentRepository;
import com.example.student_system.service.StudentService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Optional;

@Service
@Transactional
public class StudentServiceImpl implements StudentService {

    private static final Logger logger = LoggerFactory.getLogger(StudentServiceImpl.class);
    private final StudentRepository studentRepository;

    public StudentServiceImpl(StudentRepository studentRepository) {
        this.studentRepository = studentRepository;
    }

    @Override
    public Student saveStudent(Student student) {
        logger.debug("开始保存学生信息: {}", student);
        // 验证学生信息
        validateStudent(student);

        // 检查学号是否已存在
        if (student.getId() == null) {
            // 新增学生时检查学号唯一性
            if (isStudentNumberExists(student.getStudentNumber())) {
                throw new StudentException("学号 " + student.getStudentNumber() + " 已存在");
            }
        } else {
            // 更新学生信息时，确保不会与其他学生的学号冲突
            Optional<Student> existingStudent = studentRepository.findByStudentNumber(student.getStudentNumber());
            if (existingStudent.isPresent() && !existingStudent.get().getId().equals(student.getId())) {
                throw new StudentException("学号 " + student.getStudentNumber() + " 已被其他学生使用");
            }
        }

        try {
            Student savedStudent = studentRepository.save(student);
            logger.info("学生信息保存成功: {}", savedStudent);
            return savedStudent;
        } catch (Exception e) {
            logger.error("保存学生信息失败", e);
            throw new StudentException("保存学生信息失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(readOnly = true)
    public Student getStudentById(Long id) {
        logger.debug("根据ID查询学生: {}", id);
        if (id == null) {
            throw new StudentException("学生ID不能为空");
        }
        return studentRepository.findById(id)
                .orElseThrow(() -> new StudentException("未找到ID为 " + id + " 的学生"));
    }

    @Override
    @Transactional(readOnly = true)
    public Student getStudentByNumber(String studentNumber) {
        logger.debug("根据学号查询学生: {}", studentNumber);
        if (!StringUtils.hasText(studentNumber)) {
            throw new StudentException("学号不能为空");
        }
        return studentRepository.findByStudentNumber(studentNumber)
                .orElseThrow(() -> new StudentException("未找到学号为 " + studentNumber + " 的学生"));
    }

    @Override
    @Transactional(readOnly = true)
    public List<Student> getAllStudents() {
        logger.debug("查询所有学生");
        return studentRepository.findAll();
    }

    @Override
    @Transactional(readOnly = true)
    public List<Student> getStudentsByName(String name) {
        logger.debug("根据姓名查询学生: {}", name);
        if (!StringUtils.hasText(name)) {
            throw new StudentException("搜索的姓名不能为空");
        }
        return studentRepository.findByNameContaining(name.trim());
    }

    @Override
    @Transactional(readOnly = true)
    public List<Student> getStudentsByClass(String className) {
        logger.debug("根据班级查询学生: {}", className);
        if (!StringUtils.hasText(className)) {
            throw new StudentException("搜索的班级名称不能为空");
        }
        return studentRepository.findByClassName(className.trim());
    }

    @Override
    public void deleteStudent(Long id) {
        logger.debug("开始删除学生: {}", id);
        if (id == null) {
            throw new StudentException("学生ID不能为空");
        }
        
        if (!studentRepository.existsById(id)) {
            throw new StudentException("未找到ID为 " + id + " 的学生");
        }
        
        try {
            studentRepository.deleteById(id);
            logger.info("成功删除学生: {}", id);
        } catch (Exception e) {
            logger.error("删除学生失败", e);
            throw new StudentException("删除学生失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(readOnly = true)
    public boolean isStudentNumberExists(String studentNumber) {
        logger.debug("检查学号是否存在: {}", studentNumber);
        if (!StringUtils.hasText(studentNumber)) {
            throw new StudentException("学号不能为空");
        }
        return studentRepository.findByStudentNumber(studentNumber).isPresent();
    }

    /**
     * 验证学生信息
     * @param student 待验证的学生对象
     * @throws StudentException 如果验证失败
     */
    private void validateStudent(Student student) {
        if (student == null) {
            throw new StudentException("学生信息不能为空");
        }

        if (!StringUtils.hasText(student.getStudentNumber())) {
            throw new StudentException("学号不能为空");
        }

        if (!student.getStudentNumber().matches("^[A-Za-z0-9]+$")) {
            throw new StudentException("学号只能包含字母和数字");
        }

        if (!StringUtils.hasText(student.getName())) {
            throw new StudentException("姓名不能为空");
        }

        if (!StringUtils.hasText(student.getGender())) {
            throw new StudentException("性别不能为空");
        }

        if (student.getAge() == null || student.getAge() < 15 || student.getAge() > 100) {
            throw new StudentException("年龄必须在15-100之间");
        }

        if (!StringUtils.hasText(student.getClassName())) {
            throw new StudentException("班级不能为空");
        }

        if (student.getEnrollmentDate() == null) {
            throw new StudentException("入学日期不能为空");
        }
    }
}